package com.example.file_demo.util;

import com.example.file_demo.config.HccCommonConfig;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class FileUploadUtil {

    /**
     * 从MultipartFile获取InputStream
     *
     * @param multipartFile MultipartFile对象
     * @return InputStream对象
     * @throws IOException 如果发生I/O错误
     */
    public static InputStream getInputStreamFromMultipartFile(MultipartFile multipartFile) throws IOException {
        return multipartFile.getInputStream();
    }

    /**
     * 如果确实需要FileInputStream，可以将MultipartFile内容保存到一个临时文件
     *
     * @param multipartFile MultipartFile对象
     * @return FileInputStream对象
     * @throws IOException 如果发生I/O错误
     */
    public static FileInputStream getFileInputStreamFromMultipartFile(MultipartFile multipartFile) throws IOException {
        // 创建一个临时文件来保存MultipartFile的内容
        File tempFile = File.createTempFile("uploaded", multipartFile.getOriginalFilename());
        tempFile.deleteOnExit(); // JVM退出时删除临时文件

        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
            // 将MultipartFile的内容写入临时文件
            fos.write(multipartFile.getBytes());
        }

        // 从临时文件获取FileInputStream
        return new FileInputStream(tempFile);
    }

    private static final String UPLOAD_DIR = "/path/to/upload/directory"; // 替换为实际的上传目录

    public static List<String> saveFiles(List<MultipartFile> files) {
        List<String> fileNames = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                // 获取文件名并保存文件
                String fileName = org.springframework.util.StringUtils.cleanPath(file.getOriginalFilename());
                Path filePath = Paths.get(UPLOAD_DIR, fileName).normalize();
                Files.createDirectories(filePath.getParent());
                Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
                fileNames.add(fileName);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileNames;
    }

//    public static Map<String, File> saveFilesForEach(List<MultipartFile> files) throws IOException {
//        Map<String, File> map = new HashMap<>();
//        for (MultipartFile file : files) {
//            String baseDir = HccCommonConfig.getUploadPath(); // 确保这个方法返回正确的上传基本路径
//            String originalFilename = file.getOriginalFilename();
//            String contentType = file.getContentType();
//
//            // 解析文件名以获取层级关系
//            String[] parts = org.springframework.util.StringUtils.tokenizeToStringArray(originalFilename, "/\\"); // 使用 / 或 \ 作为分隔符
//            if (parts.length > 1) {
//                // 构造层级关系字符串，不包含尾部斜杠
//                StringBuilder hierarchy = new StringBuilder();
//                for (int i = 0; i < parts.length - 1; i++) {
//                    hierarchy.append(parts[i]);
//                    if (i < parts.length - 2) {
//                        hierarchy.append("/");
//                    }
//                }
//                String folderHierarchy = hierarchy.toString();
//
//                // 文件名（不包括层级路径）
//                String fileName = parts[parts.length - 1];
//
//                // 构建完整路径
//                Path basePath = Paths.get(baseDir).normalize();
//                Path folderPath = basePath.resolve(folderHierarchy).normalize();
//                Path filePath = folderPath.resolve(fileName).normalize();
//                Files.createDirectories(folderPath);
//
//                // 保存文件
//                try (InputStream inputStream = file.getInputStream()) {
//                    Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
//                }
//
//                // 将保存后的文件对象添加到映射中
//                File savedFile = filePath.toFile();
//                if (savedFile.exists()) {
//                    // 使用层级关系字符串和文件名作为键
//                    String key = folderHierarchy + "/" + fileName;
//                    map.put(key, savedFile);
//                }
//            }
//        }
//        return map;
//    }

    public static Map<String, File> saveFilesForEach(List<MultipartFile> files) throws IOException {
        Map<String, File> map = new HashMap<>();
        for (MultipartFile file : files) {
            String baseDir = HccCommonConfig.getUploadPath(); // 确保这个方法返回正确的上传基本路径
            String originalFilename = file.getOriginalFilename();

            // 解析文件名以获取层级关系
            String[] parts = org.springframework.util.StringUtils.tokenizeToStringArray(originalFilename, "/\\"); // 使用 / 或 \ 作为分隔符
            if (parts.length > 1) {
                // 构造层级关系字符串，不包含尾部斜杠
                StringBuilder hierarchy = new StringBuilder();
                for (int i = 0; i < parts.length - 1; i++) {
                    hierarchy.append(parts[i]);
                    if (i < parts.length - 2) {
                        hierarchy.append("/");
                    }
                }
                String folderHierarchy = hierarchy.toString();

                // 文件名（不包括层级路径）
                String fileName = parts[parts.length - 1];

                String fileNamePath = extractFilename(file.getOriginalFilename(), file.getContentType());
                fileNamePath = removeLastSegment(fileNamePath);
                String absPath = getAbsoluteFile(baseDir, fileNamePath).getAbsolutePath();
                // 构建完整路径
                Path folderPath = Paths.get(absPath).normalize().resolve(folderHierarchy).normalize();
                Path filePath = folderPath.resolve(fileName).normalize();
                Files.createDirectories(folderPath);

                // 保存文件
                try (InputStream inputStream = file.getInputStream()) {
                    Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
                }

                // 将保存后的文件对象添加到映射中
                File savedFile = filePath.toFile();
                if (savedFile.exists()) {
                    // 使用层级关系字符串和文件名作为键
                    String key = folderHierarchy + "/" + fileName;
                    map.put(key, savedFile);
                }
            }
        }
        return map;
    }

    /**
     * 编码文件名
     */
    public static String extractFilename(String originalFile,String contentType) {
        return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
                FilenameUtils.getBaseName(originalFile), new AtomicInteger(1), getExtension(originalFile, contentType));
    }

    /**
     * 获取文件名的后缀
     *
     * @param originalFile 表单文件
     * @param contentType
     * @return 后缀名
     */
    public static String getExtension(String originalFile,String contentType) {
        String extension = FilenameUtils.getExtension(originalFile);
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(Objects.requireNonNull(contentType));
        }
        return extension;
    }

    public static File getAbsoluteFile(String uploadDir, String fileName) throws IOException {
        File desc = new File(uploadDir + File.separator + fileName);

        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc;
    }

    public static File convertMultipartFileToFile(MultipartFile multipartFile) {
        File file = new File(multipartFile.getOriginalFilename());
        try (FileOutputStream fos = new FileOutputStream(file);
             InputStream is = multipartFile.getInputStream()) {
            int len;
            byte[] buffer = new byte[1024];
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;

    }

    public static String removeLastSegment(String input) {
        int lastIndex = input.lastIndexOf('/');
        if (lastIndex != -1) {
            return input.substring(0, lastIndex);
        } else {
            return input;
        }
    }
}